CodeForces-1152-B Neko Performs Cat Furrier Transform

Topic link:Neko Performs Cat Furrier Transform
Description:
Cat Furrier Transform is a popular algorithm among cat programmers to create longcats. As one of the greatest cat programmers ever exist, Neko wants to utilize this algorithm to create the perfect longcat.

Assume that we have a cat with a number x. A perfect longcat is a cat with a number equal 2m−1 for some non-negative integer m. For example, the numbers 0, 1, 3, 7, 15 and so on are suitable for the perfect longcats.

In the Cat Furrier Transform, the following operations can be performed on x:

(Operation A): you select any non-negative integer n and replace x with x⊕(2n−1), with ⊕ being a bitwise XOR operator.
(Operation B): replace x with x+1.
The first applied operation must be of type A, the second of type B, the third of type A again, and so on. Formally, if we number operations from one in the order they are executed, then odd-numbered operations must be of type A and the even-numbered operations must be of type B.

Neko wants to produce perfect longcats at industrial scale, thus for each cat Neko only wants to perform at most 40 operations. Can you help Neko writing a transformation plan?

Note that it is not required to minimize the number of operations. You just need to use no more than 40 operations.

Input
The only line contains a single integer x (1≤x≤106).

Output
The first line should contain a single integer t (0≤t≤40) — the number of operations to apply.

Then for each odd-numbered operation print the corresponding number ni in it. That is, print ⌈t2⌉ integers ni (0≤ni≤30), denoting the replacement x with x⊕(2ni−1) in the corresponding step.

If there are multiple possible answers, you can print any of them. It is possible to show, that there is at least one answer in the constraints of this problem.

Examples
input
39
output
4
5 3
input
1
output
0
input
7
output
0
Note
In the first test, one of the transforms might be as follows: 39→56→57→62→63. Or more precisely:

Pick n=5. x is transformed into 39⊕31, or 56.
Increase x by 1, changing its value to 57.
Pick n=3. x is transformed into 57⊕7, or 62.
Increase x by 1, changing its value to 63=26−1.
In the second and third test, the number already satisfies the goal requirement.

There are some differences between the description on my blog and the real,so I put a real piture here.

Intentional analysis:
The most important solution to this problem is to simulate.To solve this problem,you better use binary processing.If a number is equal to pow(2,n)-1,then its binary is 1 for each bit.So we only need to process the binary bits of the number to be processed.First, find the highest bit with a binary bit of 0.Then,Each of the next inversions.If the conditions are not met, add 1.This loops until the value that satisfies the condition appears.

Click to see Chinese Intentional analysis 这道题最重要的思想就是模拟,因为一个数如果是2的n次方减1,那么它的二进制位每一位都是1。因此这道题就可以对输入的数以二进制位的形式进行操作。首先找到最高位的0,然后对这一位以下的所有的二进制位与1进行异或,异或完判断是否满足条件,如果不满足就加一在进行判断,还不行的话就开始下一次循环,直到找到满足条件的数跳出循环即可。思想应该是很容易懂的,难得地方就是实现。一开始我想用bitset来做,但是没成功,还是老老实实的用数组做吧。

Code:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    vector<int> v;
    int B[30],n,ans=0,t,now=0;
    cin>>n;
    t=n;
    while(t)
    {
        B[now++]=t%2;
        t/=2;
    }
    int i=now-1;
    for(;i>=0;i--)
    {
        if(B[i]==0)
        {
            v.push_back(i+1);
            bool flag=0;
            for(int j=i;j>=0;j--)
            {
                B[j]^=1;
                if(B[j]==0&&j!=0)
                    flag=1;
            }
            ans++;
            if(flag==0)
            {
                if(B[0]==0)
                {
                    B[0]++;
                    ans++;
                }
                i=-1;
                break;
            }
            B[0]++;
            ans++;
            for(int k=0;k<i;k++)
            {
                if(B[k]>1)
                {
                    B[k]=0;
                    B[k+1]++;
                }
                else
                    break;
            }
        }
        if(i==-1)
        break;
    }
    cout<<ans<<endl;
    for(int j=0;j<v.size();j++)
    {
        cout<<v[j]<<" ";
        if(j==v.size()-1)
            puts("");
    }
    return 0;
}